package cn.vcjf.weapp.common.wxpay;

import cn.vcjf.weapp.common.util.DateUtils;
import cn.vcjf.weapp.common.util.SysParamUtil;
import cn.vcjf.weapp.common.web.TableResult;
import cn.vcjf.weapp.common.wxpay.sdk.WXPay;
import cn.vcjf.weapp.common.wxpay.sdk.WXPayConfigImpl;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;

import javax.servlet.http.HttpServletRequest;
import java.util.*;


/**
 * @Auther: zhengzihang
 * @Date: 2018/7/11 16:06
 * @Description:
 */
public abstract class AbstractWxpayService {
	private static final Random RANDOM = new Random();
	public static String BASE_URL=SysParamUtil.getParam("online.base.common.callbackurl");//"http://vcjf.s1.natapp.cc/";//
	private Logger logger = LogManager.getLogger(AbstractWxpayService.class);
	/**
	 * 支付异步回调地址
	 */
	public abstract String getNotifyOrderUrl();
	/**
	 * 获取客户端Ip地址
	 *
	 * @return
	 */
	public static String getIpAddr(HttpServletRequest request) {
		// 通过请求头获取ip地址
		String ip = request.getHeader("x-forwarded-for");
		// 判断ip地址是否是代理地址
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		// 判断ip地址是否是代理地址
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		// 判断ip地址是否是代理地址
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		if(StringUtils.isNotEmpty(ip) && ip.indexOf(",")>0){
			return ip.split(",")[0];
		}
		return ip;
	}
	/**
	 *  微信下单
	 * @param openid
	 * @param productName
	 * @param orderNo
	 * @param amount    单位为分不可有小数,请自行转化
	 * @param ip
	 * @return
	 */
	public TableResult doWxUnifiedOrder(String openid, String productName, String orderNo, String amount, String ip){
		WXPayConfigImpl config=new WXPayConfigImpl();

		WXPay wxPay = null;
		TableResult result=TableResult.ErrorResult();
		try {
			wxPay = new WXPay(config, getNotifyOrderUrl() , false, false);

			Map<String, String> reqData=new TreeMap<>();
			reqData.put("body",productName);       //商品描述
			reqData.put("out_trade_no",orderNo);   //商户订单号
			reqData.put("total_fee",amount.toString());      //订单总金额，单位为分
			reqData.put("spbill_create_ip",ip);   //APP和网页支付提交用户端ip，Native支付填调用微信支付API的机器IP
			reqData.put("openid",openid);
			reqData.put("sign_type","MD5");
			reqData.put("trade_type","JSAPI");     //JSAPI 公众号支付
			// NATIVE 扫码支付
			//  APP APP支付
			reqData.put("time_start",DateUtils.getDate("yyyyMMddHHmmss")); //交易起始时间
			//交易结束时间
			Date data=new Date(System.currentTimeMillis()+30L*60*1000);
			reqData.put("time_expire",DateUtils.formatDate(data,"yyyyMMddHHmmss"));

			Map<String, String> map = wxPay.unifiedOrder(reqData);

			logger.info("微信下单参数:{}",map);

			SortedMap<String, String> param = new TreeMap<>();
			if("SUCCESS".equals(map.get("return_code"))&&"SUCCESS".equals(map.get("result_code"))) {

				result=TableResult.OKResult("下单成功");

				String timeStamp = String.valueOf(System.currentTimeMillis() / 1000L);
				String packAge = "prepay_id=" + map.get("prepay_id");
				param.put("appId", WXPayConfigImpl.APP_ID);
				param.put("timeStamp",timeStamp);
				param.put("nonceStr", getRandomStr());
				param.put("package", packAge);
				param.put("signType", "MD5");

				String signature = sign(param, WXPayConfigImpl.KEY);
				param.put("paySign", signature);

//				String paramString = HttpClientUtils.buildMapToString(param);
				result.setData(param);

				logger.info("微信下单成功PayUrl:{}",result.getData());
			}else {
				result.setMsg(map.get("retmsg")+map.get("return_msg"));
			}

		} catch (Exception e) {
			e.printStackTrace();
			logger.error("微信下单异常:{}",e);
		}
		return result;
	}

	public static String getRandomStr() {
		StringBuilder sb = new StringBuilder();

		for(int i = 0; i < 16; ++i) {
			sb.append("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".charAt(RANDOM.nextInt("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".length())));
		}

		return sb.toString();
	}
	public static String sign(Map<String, String> params, String signKey) {
		SortedMap<String, String> sortedMap = new TreeMap(params);
		StringBuilder toSign = new StringBuilder();
		Iterator var4 = sortedMap.keySet().iterator();

		while(var4.hasNext()) {
			String key = (String)var4.next();
			String value = (String)params.get(key);
			if (StringUtils.isNotEmpty(value) && !"sign".equals(key) && !"key".equals(key)) {
				toSign.append(key).append("=").append(value).append("&");
			}
		}

		toSign.append("key=").append(signKey);
		System.out.println(toSign.toString());
		return DigestUtils.md5Hex(toSign.toString()).toUpperCase();
	}
	public static void main(String[] args) {
		System.out.println(DigestUtils.md5Hex("appId=wxf016478ca445d71d&nonceStr=lUhjfR0bALNevfZithaMT0maztcOIlkC&package=prepay_id=wx1216472259634982b22d087a3275734649&signType=MD5&timeStamp=1531385245&key=atrQKRYwAzKOVqA70zcZpVL5oK0eFs8N").toUpperCase());
	}
}
